package com.greyshark.lib.bluetooth.scan;

import android.bluetooth.BluetoothAdapter;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.greyshark.lib.bluetooth.entity.ScanDeviceEntity;
import com.greyshark.lib.bluetooth.scan.scanner.BluetoothLeScannerCompat;
import com.greyshark.lib.bluetooth.scan.scanner.ScanCallback;
import com.greyshark.lib.bluetooth.scan.scanner.ScanFilter;
import com.greyshark.lib.bluetooth.scan.scanner.ScanResult;
import com.greyshark.lib.bluetooth.scan.scanner.ScanSettings;

import java.util.ArrayList;
import java.util.List;

public class ResidentScanner {
    private final static String TAG = ResidentScanner.class.getSimpleName();
    private static volatile ResidentScanner instance;

    private ResidentScanner() {

    }

    public static ResidentScanner getInstance() {
        if (instance == null) {
            synchronized (ResidentScanner.class) {
                if (instance == null) {
                    instance = new ResidentScanner();
                }
            }
        }
        return instance;
    }


    /**
     * 是否运行中
     */
    private boolean running = false;

    //private String

    /**
     * 是否运行中
     *
     * @return
     */
    public boolean isRunning() {
        return running;
    }

    /**
     * 当前监听的扫描mac
     */
    private String currentMac = "";
    private BleScanResultListener mBleScanResultListener;

    /**
     * 开始监听
     */
    public void startMonitorScanByMac(String mac, BleScanResultListener listener) {
        currentMac = mac;
        mBleScanResultListener = listener;
    }

    public interface BleScanResultListener {
        void onBleResult(ScanResult result);
    }


    /**
     * 初始化开启扫描
     */
    public void initScanner() {
        try {
            if (BluetoothAdapter.getDefaultAdapter().isEnabled() && !running) {
                final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
                final ScanSettings settings = new ScanSettings.Builder()
                        .setLegacy(false)
                        //SCAN_MODE_LOW_POWER - 在低功耗模式下执行蓝牙 LE 扫描。这是默认扫描模式，因为它消耗的电量最少。扫描仪将扫描 0.5 秒，然后休息 4.5 秒。蓝牙 LE 设备应经常进行广告（至少每 100 毫秒一次），以便通过此模式被发现，否则扫描间隔可能会错过部分甚至全部广告事件。如果扫描应用程序不在前台，则可以强制执行此模式。
                        //SCAN_MODE_BALANCED - 在平衡功率模式下执行蓝牙 LE 扫描。扫描结果的返回速率可以在扫描频率和功耗之间提供良好的权衡。扫描仪将扫描 2 秒，然后闲置 3 秒。
                        //SCAN_MODE_LOW_LATENCY - 使用最高占空比进行扫描。建议仅当应用程序在前台运行时使用此模式。
                        //SCAN_MODE_OPPORTUNISTIC - 一种特殊的蓝牙 LE 扫描模式。使用此扫描模式的应用程序将被动侦听其他扫描结果，而无需自行启动 BLE 扫描。
                        .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                        .setReportDelay(5000)
                        .setUseHardwareBatchingIfSupported(false)
                        .build();
                final List<ScanFilter> filters = new ArrayList<>();
                filters.add(new ScanFilter.Builder().setServiceUuid(null).build());
                scanner.startScan(filters, settings, mScanCallback);
                running = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private final ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(final int callbackType, @NonNull final ScanResult result) {
            // do nothing
        }

        @Override
        public void onBatchScanResults(@Nullable final List<ScanResult> results) {
            if (results != null && !results.isEmpty()) {
                for (ScanResult r : results) {
                    //{"advertisingSid":255,"device":{},"eventType":16,"periodicAdvertisingInterval":0,"primaryPhy":1,"rssi":-89,"scanRecord":
                    // {"advertiseFlags":-1,"bytes":[30,-1,6,0,1,9,32,2,18,96,42,49,26,15,-25,77,-35,-122,112,60,-70,47,-97,113,2,-117,-65,122,45,-31,33],
                    // "manufacturerSpecificData":{},"txPowerLevel":-2147483648},"secondaryPhy":0,"timestampNanos":29286271353132,"txPower":127}

                    String bluetoothName = r.getDevice().getName();
                    String bluetoothAddress = r.getDevice().getAddress();
                    if (bluetoothName != null && !bluetoothName.isEmpty()) {
                        if (TextUtils.equals(bluetoothAddress, currentMac)) {
                            if (mBleScanResultListener != null) {
                                mBleScanResultListener.onBleResult(r);
                            }
                        }
                    }
                }
            }
        }

        @Override
        public void onScanFailed(final int errorCode) {
            // should never be called
        }
    };

    /**
     * 释放资源
     */
    public void releaseScanner() {
        try {
            if (running) {
                final BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
                scanner.stopScan(mScanCallback);
                running = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
